package com.chesnutconsulting.otbasket.image.finder.artesia;

import com.artesia.common.exception.BaseTeamsException;
import com.artesia.entity.TeamsIdentifier;
import com.artesia.metadata.MetadataField;
import com.artesia.metadata.services.MetadataServices;
import com.artesia.security.SecuritySession;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * User: kandhari
 * Date: 3/7/13 11:03 PM
 * <p/>
 * Document me
 */
@Component
public class OtMetadataFinder {
    protected final Cache<String, String> promptCache = CacheBuilder.newBuilder()
            .expireAfterWrite(24, TimeUnit.HOURS)
            .build();

    protected MetadataServices metadataServices;
    protected OtBasketConfiguration academyBasketConfiguration;

    private static final Logger LOGGER = LoggerFactory.getLogger(OtMetadataFinder.class);

    @Inject
    public OtMetadataFinder(OtBasketConfiguration academyBasketConfiguration) {
        this.metadataServices = MetadataServices.getInstance();
        this.academyBasketConfiguration = academyBasketConfiguration;
    }

    public String getPrompt(final String fieldId) {
        try {
            return promptCache.get(fieldId, new Callable<String>() {
                public String call() throws Exception {
                    return findFieldPrompt(fieldId);
                }
            });
        } catch (ExecutionException ee) {
            LOGGER.error("An error occurred while loading field id=" + fieldId, ee);
            throw new RuntimeException("An error occurred while loading field", ee);
        }
    }

    String findFieldPrompt(String fieldId) {
        String prompt = "Not Found";
        try {
            MetadataField[] matchingFields = retrieveMetadataFieldsById(new TeamsIdentifier(fieldId));
            for(MetadataField field : matchingFields) {
                if(fieldId.equalsIgnoreCase(field.getId().getTeamsId())) {
                    prompt = field.getPrompt();
                    break;
                }
            }
        } catch (BaseTeamsException bte) {
            LOGGER.warn(String.format("Couldn't find Field with id=%s", fieldId));
        }

        return prompt;
    }

    MetadataField[] retrieveMetadataFieldsById(TeamsIdentifier id) throws BaseTeamsException {
        return metadataServices.retrieveFieldsByIds(new TeamsIdentifier[]{id}, getSecuritySession());
    }

    protected SecuritySession getSecuritySession() throws BaseTeamsException {
        try {
            return academyBasketConfiguration.getSession();
        } catch (BaseTeamsException e) {
            LOGGER.error("An error occurred while getting creating an Artesia session", e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("An error occurred while getting creating an Artesia session", e);
            throw new RuntimeException(e);
        }
    }
}
